package com.example.statemachine.core;

import com.example.statemachine.event.StateChangeEvent;
import com.example.statemachine.support.StateTransitionProcessor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Component
public class StateMachineEngine implements ApplicationContextAware {

    private final StateTransitionProcessor processor;
    private ApplicationContext applicationContext;

    public StateMachineEngine(StateTransitionProcessor processor) {
        this.processor = processor;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Transactional(rollbackFor = Exception.class)
    public <T> TransitionResult<T> executeTransition(TransitionRequest<T> request, Class<T> entityClass) {
        try {
            // 获取当前状态
            T entity = request.getEntityLoader().get();
            if (entity == null) {
                throw new StateMachineException("业务实体不存在");
            }

            log.debug("开始执行状态转换: {} -> {}, 操作人: {}",
                    request.getCurrentState(), request.getEvent(),
                    request.getContext().getOperator());

            // 执行状态转换
            TransitionResult<T> result = processor.processTransition(entity, request, entityClass);

            // 发布状态变更事件前，确保context中的event不为null
            if (request.getContext().getEvent() == null) {
                log.warn("状态转换上下文中的event为null，设置为请求的event: {}", request.getEvent());
                request.getContext().setEvent(request.getEvent());
            }

            // 发布状态变更事件
            applicationContext.publishEvent(new StateChangeEvent(
                    result.getEntity(),
                    result.getPreviousState(),
                    result.getCurrentState(),
                    request.getContext()
            ));

            log.debug("状态转换完成: {} -> {} -> {}",
                    result.getPreviousState(), result.getCurrentState(), request.getEvent());

            return result;

        } catch (Exception e) {
            log.error("状态转换执行失败: {}", request.getContext(), e);
            throw new StateMachineException("状态转换失败: " + e.getMessage(), e);
        }
    }
}